<template>
  <div class="form-builder">
    <div class="builder-container">
      <div class="components-panel">
        <h3>组件列表</h3>
        <div class="component-list">
          <div
            v-for="item in componentList"
            :key="item.type"
            class="component-item"
            draggable="true"
            @dragstart="handleDragStart($event, item)"
            @dblclick="handleAddComponent(item.type)">
            <el-icon><component :is="item.icon" /></el-icon>
            <span>{{ item.label }}</span>
          </div>
        </div>
      </div>

      <div class="form-panel">
        <div class="form-header">
          <h3>表单预览</h3>
          <div class="form-actions">
            <el-button type="primary" size="small" @click="handleSave">保存表单</el-button>
            <el-button type="success" size="small" @click="handlePreview">预览</el-button>
            <el-button type="warning" size="small" @click="handleClear">清空</el-button>
          </div>
        </div>
        <div class="form-container" @dragover.prevent @drop="handleDrop">
          <el-form :model="formData" label-width="100px" v-if="formItems.length > 0">
            <template v-for="(item, index) in formItems" :key="index">
              <div class="form-item-wrapper" @click="handleSelectItem(index)">
                <el-form-item :label="item.label">
                  <!-- 输入框 -->
                  <el-input
                    v-if="item.type === 'input'"
                    v-model="formData[item.prop]"
                    :placeholder="item.placeholder" />

                  <!-- 多行文本 -->
                  <el-input
                    v-if="item.type === 'textarea'"
                    v-model="formData[item.prop]"
                    type="textarea"
                    :rows="3"
                    :placeholder="item.placeholder" />

                  <!-- 选择框 -->
                  <el-select v-if="item.type === 'select'" v-model="formData[item.prop]" style="width: 100%">
                    <el-option
                      v-for="option in item.options"
                      :key="option.value"
                      :label="option.label"
                      :value="option.value" />
                  </el-select>

                  <!-- 日期选择器 -->
                  <el-date-picker
                    v-if="item.type === 'date'"
                    v-model="formData[item.prop]"
                    type="date"
                    style="width: 100%" />

                  <!-- 日期时间选择器 -->
                  <el-date-picker
                    v-if="item.type === 'datetime'"
                    v-model="formData[item.prop]"
                    type="datetime"
                    style="width: 100%" />

                  <!-- 单选框组 -->
                  <el-radio-group v-if="item.type === 'radio'" v-model="formData[item.prop]">
                    <el-radio v-for="option in item.options" :key="option.value" :label="option.value">{{
                      option.label
                    }}</el-radio>
                  </el-radio-group>

                  <!-- 复选框组 -->
                  <el-checkbox-group v-if="item.type === 'checkbox'" v-model="formData[item.prop]">
                    <el-checkbox v-for="option in item.options" :key="option.value" :label="option.value">{{
                      option.label
                    }}</el-checkbox>
                  </el-checkbox-group>

                  <!-- 切换按钮 -->
                  <el-switch
                    v-if="item.type === 'switch'"
                    v-model="formData[item.prop]"
                    :active-text="item.activeText"
                    :inactive-text="item.inactiveText" />

                  <!-- 文件上传 -->
                  <el-upload v-if="item.type === 'upload'" class="upload-demo" action="#" :auto-upload="false">
                    <el-button type="primary">选择文件</el-button>
                  </el-upload>

                  <!-- 图片上传 -->
                  <el-upload
                    v-if="item.type === 'image'"
                    class="avatar-uploader"
                    action="#"
                    :show-file-list="false"
                    :auto-upload="false">
                    <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
                  </el-upload>

                  <!-- 链接文本 -->
                  <el-link v-if="item.type === 'link'" type="primary" :href="formData[item.prop]" target="_blank">
                    {{ item.label }}
                  </el-link>
                </el-form-item>
                <div class="item-actions">
                  <el-button link type="danger" size="small" @click.stop="handleRemoveItem(index)">删除</el-button>
                </div>
              </div>
            </template>
          </el-form>
          <div v-else class="empty-tip">从左侧拖拽组件到这里</div>
        </div>
      </div>

      <div class="property-panel" v-if="selectedIndex !== null">
        <h3>属性设置</h3>
        <el-form :model="formItems[selectedIndex]" label-width="80px">
          <el-form-item label="标签">
            <el-input v-model="formItems[selectedIndex].label" />
          </el-form-item>
          <el-form-item label="字段名">
            <el-input v-model="formItems[selectedIndex].prop" />
          </el-form-item>
          <el-form-item label="占位符" v-if="formItems[selectedIndex].type === 'input'">
            <el-input v-model="formItems[selectedIndex].placeholder" />
          </el-form-item>
          <el-form-item label="选项" v-if="['select', 'radio', 'checkbox'].includes(formItems[selectedIndex].type)">
            <div v-for="(option, i) in formItems[selectedIndex].options" :key="i" class="option-item">
              <el-input v-model="option.label" placeholder="选项文本" />
              <el-input v-model="option.value" placeholder="选项值" />
              <el-button type="danger" link @click="removeOption(selectedIndex, i)">删除</el-button>
            </div>
            <el-button type="primary" link @click="addOption(selectedIndex)">添加选项</el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>

    <!-- 预览对话框 -->
    <el-dialog title="表单预览" v-model="previewVisible" width="600px">
      <el-form :model="formData" label-width="100px">
        <el-form-item v-for="(item, index) in formItems" :key="index" :label="item.label">
          <!-- 输入框 -->
          <el-input v-if="item.type === 'input'" v-model="formData[item.prop]" :placeholder="item.placeholder" />

          <!-- 多行文本 -->
          <el-input
            v-if="item.type === 'textarea'"
            v-model="formData[item.prop]"
            type="textarea"
            :rows="3"
            :placeholder="item.placeholder" />

          <!-- 选择框 -->
          <el-select v-if="item.type === 'select'" v-model="formData[item.prop]" style="width: 100%">
            <el-option v-for="option in item.options" :key="option.value" :label="option.label" :value="option.value" />
          </el-select>

          <!-- 日期选择器 -->
          <el-date-picker v-if="item.type === 'date'" v-model="formData[item.prop]" type="date" style="width: 100%" />

          <!-- 日期时间选择器 -->
          <el-date-picker
            v-if="item.type === 'datetime'"
            v-model="formData[item.prop]"
            type="datetime"
            style="width: 100%" />

          <!-- 单选框组 -->
          <el-radio-group v-if="item.type === 'radio'" v-model="formData[item.prop]">
            <el-radio v-for="option in item.options" :key="option.value" :label="option.value">{{
              option.label
            }}</el-radio>
          </el-radio-group>

          <!-- 复选框组 -->
          <el-checkbox-group v-if="item.type === 'checkbox'" v-model="formData[item.prop]">
            <el-checkbox v-for="option in item.options" :key="option.value" :label="option.value">{{
              option.label
            }}</el-checkbox>
          </el-checkbox-group>

          <!-- 切换按钮 -->
          <el-switch
            v-if="item.type === 'switch'"
            v-model="formData[item.prop]"
            :active-text="item.activeText"
            :inactive-text="item.inactiveText" />

          <!-- 文件上传 -->
          <el-upload v-if="item.type === 'upload'" class="upload-demo" action="#" :auto-upload="false">
            <el-button type="primary">选择文件</el-button>
          </el-upload>

          <!-- 图片上传 -->
          <el-upload
            v-if="item.type === 'image'"
            class="avatar-uploader"
            action="#"
            :show-file-list="false"
            :auto-upload="false">
            <el-icon class="avatar-uploader-icon"><Plus /></el-icon>
          </el-upload>

          <!-- 链接文本 -->
          <el-link v-if="item.type === 'link'" type="primary" :href="formData[item.prop]" target="_blank">
            {{ item.label }}
          </el-link>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="previewVisible = false">关闭</el-button>
        <el-button type="primary" @click="handlePreviewSubmit">提交</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {
  Edit,
  Select,
  Calendar,
  Check,
  CircleCheck,
  Document,
  Switch,
  Upload,
  Timer,
  Link,
  Picture,
  Plus,
} from "@element-plus/icons-vue";

// 可用组件列表
const componentList = [
  { type: "input", label: "输入框", icon: "Edit" },
  { type: "textarea", label: "多行文本", icon: "Document" },
  { type: "select", label: "下拉选择", icon: "Select" },
  { type: "date", label: "日期选择", icon: "Calendar" },
  { type: "datetime", label: "日期时间", icon: "Timer" },
  { type: "radio", label: "单选框组", icon: "Check" },
  { type: "checkbox", label: "复选框组", icon: "CircleCheck" },
  { type: "switch", label: "切换按钮", icon: "Switch" },
  { type: "upload", label: "文件上传", icon: "Upload" },
  { type: "image", label: "图片上传", icon: "Picture" },
  { type: "link", label: "链接文本", icon: "Link" },
];

// 表单项列表
const formItems = ref([]);
// 表单数据
const formData = reactive({});
// 选中的表单项索引
const selectedIndex = ref(null);
// 预览对话框可见性
const previewVisible = ref(false);

// 处理拖拽开始
const handleDragStart = (e, item) => {
  e.dataTransfer.setData("componentType", item.type);
};

// 处理放置
const handleDrop = (e) => {
  const type = e.dataTransfer.getData("componentType");
  addComponent(type);
};

// 处理双击添加组件
const handleAddComponent = (type) => {
  if (!type) return;
  addComponent(type);
};

// 添加组件的通用方法
const addComponent = (type) => {
  if (!type) return;
  const newItem = {
    type,
    label: "新建字段",
    prop: `field_${Date.now()}`,
    placeholder: "请输入",
  };

  // 为特定类型的组件添加额外属性
  if (["select", "radio", "checkbox"].includes(type)) {
    newItem.options = [
      { label: "选项1", value: "1" },
      { label: "选项2", value: "2" },
    ];
  }

  // 为切换按钮添加文本
  if (type === "switch") {
    newItem.activeText = "开启";
    newItem.inactiveText = "关闭";
    formData[newItem.prop] = false;
  }

  // 为链接添加默认值
  if (type === "link") {
    newItem.placeholder = "请输入链接地址";
    formData[newItem.prop] = "https://";
  }

  formItems.value.push(newItem);
  if (!formData[newItem.prop]) {
    formData[newItem.prop] = type === "checkbox" ? [] : "";
  }

  selectedIndex.value = formItems.value.length - 1;
  ElMessage.success("添加组件成功");
};

// 处理选择表单项
const handleSelectItem = (index) => {
  selectedIndex.value = index;
};

// 处理删除表单项
const handleRemoveItem = (index) => {
  formItems.value.splice(index, 1);
  if (selectedIndex.value === index) {
    selectedIndex.value = null;
  }
};

// 添加选项
const addOption = (itemIndex) => {
  formItems.value[itemIndex].options.push({
    label: "新选项",
    value: Date.now().toString(),
  });
};

// 删除选项
const removeOption = (itemIndex, optionIndex) => {
  formItems.value[itemIndex].options.splice(optionIndex, 1);
};

// 处理保存
const handleSave = () => {
  ElMessage.success("表单配置已保存");
};

// 处理预览
const handlePreview = () => {
  if (formItems.value.length === 0) {
    ElMessage.warning("请先添加表单项");
    return;
  }
  previewVisible.value = true;
};

// 处理预览表单提交
const handlePreviewSubmit = () => {
  console.log("表单数据：", formData);
  ElMessage.success("提交成功");
  previewVisible.value = false;
};

// 处理清空
const handleClear = () => {
  ElMessageBox.confirm("确定要清空所有表单项吗？", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(() => {
    formItems.value = [];
    selectedIndex.value = null;
    Object.keys(formData).forEach((key) => {
      delete formData[key];
    });
    ElMessage.success("已清空");
  });
};
</script>

<style scoped>
.form-builder {
  background-color: #fff;
  padding: 20px;
  border-radius: 4px;
  height: calc(100vh - 120px);
  overflow: hidden;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.builder-container {
  display: flex;
  gap: 20px;
  height: 100%;
}

.components-panel {
  width: 200px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 20px;
  height: 100%;
  overflow-y: auto;
  background-color: #f8f9fb;
}

.component-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.component-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  cursor: move;
  transition: all 0.2s;
  user-select: none;
  background-color: #fff;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
  position: relative;
}

.component-item:hover {
  border-color: #409eff;
  color: #409eff;
  background-color: #ecf5ff;
  transform: translateY(-1px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.component-item::after {
  content: "双击添加";
  position: absolute;
  right: 10px;
  color: #909399;
  font-size: 12px;
  opacity: 0;
  transition: opacity 0.2s;
}

.component-item:hover::after {
  opacity: 1;
}

.form-panel {
  flex: 1;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
  background-color: #f8f9fb;
}

.form-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  flex-shrink: 0;
}

.form-container {
  flex: 1;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 20px;
  overflow-y: auto;
  background-color: #fff;
}

.empty-tip {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #909399;
  font-size: 14px;
  background-color: #f8f9fb;
  border: 2px dashed #e4e7ed;
  border-radius: 6px;
}

.form-item-wrapper {
  position: relative;
  padding: 10px;
  border: 1px solid transparent;
  border-radius: 4px;
  margin-bottom: 10px;
  transition: all 0.3s;
  background-color: #fff;
}

.form-item-wrapper:hover {
  border-color: #409eff;
  background-color: #f8f9fb;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
}

.item-actions {
  position: absolute;
  right: 5px;
  top: 50%;
  transform: translateY(-50%);
  display: none;
  z-index: 1;
}

.form-item-wrapper:hover .item-actions {
  display: block;
}

.property-panel {
  width: 300px;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 20px;
  height: 100%;
  overflow-y: auto;
  background-color: #f8f9fb;
}

.option-item {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
  background-color: #fff;
  padding: 12px;
  border-radius: 4px;
  flex-wrap: wrap;
  gap: 10px;
  border: 1px solid #e4e7ed;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.option-item .el-input {
  flex: 1;
  min-width: 120px;
}

.option-item .el-button {
  margin-left: auto;
  padding: 4px 0;
}

.option-item:hover {
  border-color: #409eff;
  box-shadow: 0 2px 8px rgba(64, 158, 255, 0.1);
}

h3 {
  margin: 0 0 20px 0;
  font-size: 16px;
  color: #303133;
  font-weight: 500;
  display: flex;
  align-items: center;
  gap: 8px;
}

h3::before {
  content: "";
  width: 4px;
  height: 16px;
  background-color: #409eff;
  border-radius: 2px;
}

:deep(.el-form-item) {
  margin-bottom: 18px;
}

:deep(.el-form-item:last-child) {
  margin-bottom: 0;
}

:deep(.el-button--primary.is-link) {
  padding: 4px 0;
  height: auto;
  font-size: 13px;
}

:deep(.el-form-item__label) {
  font-weight: 500;
}

.avatar-uploader {
  width: 100%;
  text-align: left;
}

.avatar-uploader .avatar-uploader-icon {
  width: 178px;
  height: 178px;
  font-size: 28px;
  color: #8c939d;
  background-color: #f8f9fb;
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  transition: all 0.3s;
}

.avatar-uploader .avatar-uploader-icon:hover {
  border-color: #409eff;
  color: #409eff;
  background-color: #ecf5ff;
}

.avatar-uploader .el-upload {
  display: block;
  text-align: left;
}
</style>
